""" 文件描述
2024-3-6-ljp: 描述了一个绘图类, 目前拥有两个绘制图表的方法
"""

import matplotlib.pyplot as plt # 导入绘图库
import numpy as np # 导入计算库
from typing import List # 导入类型提示模块
from pathlib import Path # 导入具体路径类

class Draw(object):
    """概述:该类可以根据两个数组来绘制对应的可视化图表(具备一定风格设置)
    属性:
        (1)self.save:布尔值,用于设置是否将绘制的图表保存再当前工作目录下,默认为 false
        (2)self.save_path:Path 值,用于设置图片的保存路径,默认为 Path('.', 'code', 'source_code', 'code_assert')
        (3)self.font:字符串值,用于设置表格的文字风格
    """
    def __init__(self, save:bool=False, save_path:Path=Path('.', 'code', 'resource'), font:str='SimHei') -> None:
        self.font = font
        self.save = save
        self.save_path = save_path

        self.__number = 0 # 用于显示不同的图表的变量(对外不可见)
        plt.rcParams['font.sans-serif'] = [self.font] # 设置全局字体
        
    def bar_charts(self, x_values:List[float], y_values:List[float], title:str, xlabel:str, ylabel:str) -> None:
        """作用:根据两个元组 x_values,y_values 绘制矩形图,图标题为 title,轴名分别为 xlabel,ylabel"""
        plt.figure(self.__number)
        self.__number += 1

        plt.ylim(0.0, 1.0)
        plt.bar(x_values, y_values) 
        plt.title(title) 
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)

        if self.save:
             plt.savefig(str(self.save_path / f"{title}.png")) # 保存图片

    def scatter_charts(self, x_values:List[float], y_values:List[float], title:str, xlabel:str, ylabel:str) -> None:
        """作用:根据两个元组 x_values,y_values 绘制散点图,图标题为 title,轴名分别为 xlabel,ylabel(并且还会绘制 y_values 的平均值水平线)"""
        
        plt.figure(self.__number)
        self.__number += 1

        plt.ylim(0.0, 1.0)
        plt.scatter(x_values, y_values)
        plt.title(title)
        plt.xlabel(xlabel)
        plt.ylabel(ylabel)

        y_mean = np.mean(y_values)
        plt.plot([min(x_values), max(x_values)], [y_mean, y_mean], color='red', linewidth=2, linestyle='-')

        if self.save:
            plt.savefig(str(self.save_path / f"{title}.png")) # 保存图片

    def charts_show(self) -> None:
        """作用:显示出所有可视化图表,主要是用于 debug"""
        plt.show()